#include "MainBallEscape.h"

// Declare our game instance
MainBallEscape game;

MainBallEscape::MainBallEscape()
    : _scene(NULL)
{
}

void MainBallEscape::initialize()
{
    // Load game scene from file
    Bundle* bundle = Bundle::create("res/box.gpb");
    _scene = bundle->loadScene();
    SAFE_RELEASE(bundle);

    // Set the aspect ratio for the scene's camera to match the current resolution
    _scene->getActiveCamera()->setAspectRatio((float)getWidth() / (float)getHeight());
    
    // Get light node
    Node* lightNode = _scene->findNode("directionalLight");
    Light* light = lightNode->getLight();

    // Initialize box model
   	ballNode = _scene->findNode("box");
    Model* boxModel = ballNode->getModel();
    Material* boxMaterial = boxModel->setMaterial("res/box.material#basketball");
    boxMaterial->getParameter("u_ambientColor")->setValue(Vector3(0.7,0.7,0.7));
    boxMaterial->getParameter("u_lightColor")->setValue(light->getColor());
    boxMaterial->getParameter("u_lightDirection")->setValue(lightNode->getForwardVectorView());

    // Set the ball physics
    PhysicsRigidBody::Parameters params(1, 1, 1);
    ballNode->setCollisionObject(PhysicsRigidBody::RIGID_BODY, PhysicsCollisionShape::sphere(1), &params);

    // Workaround for a weird bullet bug... we can't remove this :s
    Node* obstacleNode = _scene->findNode("Obstacle1");
    Material* obstacleMaterial = obstacleNode->getModel()->setMaterial("res/box.material#wall");
    obstacleMaterial->getParameter("u_lightColor")->setValue(light->getColor());
    obstacleMaterial->getParameter("u_lightDirection")->setValue(lightNode->getForwardVectorView());

    // Set the gravity
    Game::getPhysicsController()->setGravity(Vector3(0, 0, -50));

    _scene->visit(this, &MainBallEscape::setupLevel);
}

bool MainBallEscape::setupLevel(Node* node) {
	std::string id = node->getId();
	if (id.find("Obstacle") == 0) {

	    Node* lightNode = _scene->findNode("directionalLight");
	    Light* light = lightNode->getLight();

	    Material* material = node->getModel()->setMaterial("res/box.material#wall");
	    material->getParameter("u_lightColor")->setValue(light->getColor());
	    material->getParameter("u_lightDirection")->setValue(lightNode->getForwardVectorView());

	    // increase scale in z so the walls are bigggg
	    node->setScaleZ(5);

		PhysicsRigidBody::Parameters params(0, 1, 1);
		params.kinematic = true;
	    Vector3 scale = node->getScale() * 2;
		node->setCollisionObject(PhysicsRigidBody::RIGID_BODY, PhysicsCollisionShape::box(Vector3(scale.x, scale.y, scale.z)), &params);
	} else if (id.find("Floor") == 0) {

	    Node* lightNode = _scene->findNode("directionalLight");
	    Light* light = lightNode->getLight();

	    Material* material = node->getModel()->setMaterial("res/box.material#floor");
	    material->getParameter("u_lightColor")->setValue(light->getColor());
	    material->getParameter("u_lightDirection")->setValue(lightNode->getForwardVectorView());

		PhysicsRigidBody::Parameters params(0, 1, 1);
		params.kinematic = true;
	    Vector3 scale = node->getScale() * 2;
		node->setCollisionObject(PhysicsRigidBody::RIGID_BODY, PhysicsCollisionShape::box(Vector3(scale.x, scale.y, scale.z), Vector3(0, 0, -scale.z / 2)), &params);
	}

	return true;
}

void MainBallEscape::finalize()
{
    SAFE_RELEASE(_scene);
}

void MainBallEscape::update(long elapsedTime)
{
    getInput();

    _scene->getActiveCamera()->getNode()->setTranslationX(ballNode->getTranslationX());
    _scene->getActiveCamera()->getNode()->setTranslationY(ballNode->getTranslationY());

    PhysicsRigidBody* rigidBody = (PhysicsRigidBody*)ballNode->getCollisionObject();
    rigidBody->applyForce(Vector3(roll, pitch, 0));
}

void MainBallEscape::render(long elapsedTime)
{
    // Clear the color and depth buffers
    clear(CLEAR_COLOR_DEPTH, Vector4::zero(), 1.0f, 0);

    // Visit all the nodes in the scene for drawing
    _scene->visit(this, &MainBallEscape::drawScene);
}

bool MainBallEscape::drawScene(Node* node)
{
    // If the node visited contains a model, draw it
    Model* model = node->getModel(); 
    if (model)
    {
        model->draw();
    }
    return true;
}

void MainBallEscape::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
{
    switch (evt)
    {
    case Touch::TOUCH_PRESS: {
        PhysicsRigidBody* rigidBody = (PhysicsRigidBody*)ballNode->getCollisionObject();
        if (ballNode->getTranslationZ() < 0.1)
        	rigidBody->applyImpulse(Vector3(0, 0, 20));
        break; }
    case Touch::TOUCH_RELEASE:
        break;
    case Touch::TOUCH_MOVE:
        break;
    };
}


void MainBallEscape::getInput()
{
	getAccelerometerValues(&pitch, &roll);
}
